package com.sh.rpc.server.tcp;

import com.sh.rpc.model.RpcRequest;
import com.sh.rpc.model.RpcResponse;
import com.sh.rpc.protocol.*;
import com.sh.rpc.registry.LocalRegistry;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import java.lang.reflect.Method;

/**
 * tcp服务器的处理器
 *
 * @author sh
 */
public class TcpServerHandler implements Handler<NetSocket> {

    @Override
    public void handle(NetSocket socket) {

        TcpBufferHandlerWrapper bufferHandlerWrapper = new TcpBufferHandlerWrapper(buffer -> {
            // 接收请求，解析
            ProtocolMessage<RpcRequest> protocolMessage;
            try {
                protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decode(buffer);
            } catch (Exception e) {
                throw new RuntimeException("协议解码错误");
            }
            RpcRequest rpcRequest = protocolMessage.getBody();  // 获取请求体  里面有方法 参数 什么的
            ProtocolMessage.Header header = protocolMessage.getHeader();
            System.out.println("收到客户端请求：" + rpcRequest);
            // 处理  构造响应对象  根据对象调用服务  粉装返回结果
            RpcResponse response = new RpcResponse();

            try {
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                response.setData(result);
                response.setDataType(method.getReturnType());
                response.setMessage("调用成功");
            } catch (Exception e) {
                e.printStackTrace();
                response.setException(e);
                response.setMessage(e.getMessage());
            }

            // 响应发送  设置头  构造协议消息    发送
            header.setType((byte) ProtocolMessageTypeEnum.RESPONSE.getKey());  // 设置头为响应类型
            header.setStatus((byte) ProtocolMessageStatusEnum.OK.getValue());
            ProtocolMessage<RpcResponse> responseProtocolMessage = new ProtocolMessage<>(header, response);
            try {
                Buffer encode = ProtocolMessageEncoder.encode(responseProtocolMessage);
                socket.write(encode);
            } catch (Exception e) {
                throw new RuntimeException("协议编码发送错误");
            }
        });
        socket.handler(bufferHandlerWrapper);

        /*netSocket.handler(buffer -> {
            // 接收请求，解析
            ProtocolMessage<RpcRequest> protocolMessage;
            try {
                protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decode(buffer);
            } catch (Exception e) {
                throw new RuntimeException("协议解码错误");
            }
            RpcRequest rpcRequest = protocolMessage.getBody();  // 获取请求体  里面有方法 参数 什么的

            // 处理  构造响应对象  根据对象调用服务  粉装返回结果
            RpcResponse response = new RpcResponse();

            try {
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                response.setData(result);
                response.setDataType(method.getReturnType());
                response.setMessage("调用成功");
            } catch (Exception e) {
                e.printStackTrace();
                response.setException(e);
                response.setMessage(e.getMessage());
            }

            // 响应发送  设置头  构造协议消息    发送
            ProtocolMessage.Header header = protocolMessage.getHeader();
            header.setType((byte) ProtocolMessageTypeEnum.RESPONSE.getKey());  // 设置头为响应类型
            ProtocolMessage<RpcResponse> responseProtocolMessage = new ProtocolMessage<>(header, response);
            try {
                Buffer encode = ProtocolMessageEncoder.encode(responseProtocolMessage);
                netSocket.write(encode);
            } catch (Exception e) {
                throw new RuntimeException("协议编码发送错误");
            }
        });*/
    }
}
